Skip to main content
Version: Next

JSON handling

Navida App consumes a lot of JSON data. It comes from multiple sources, including aok-config, plugin-config and API responses. While simple in theory, the practice proves that it's a complex task, especially when handling edge-cases, like missing or invalid data.

As of today, there are 2 mechanisms in place to process the JSON data - kotlinx.serialization and Google's Gson libraries. The former one is widely used inside open-contract library, including all of the Backend API communication. On the other hand, Navida plugins-repository focuses around Gson library. This fact originates at the API exposed by PluginConfigManager, which delivers plugin-config in a string format.

It's crucial to note that those two libraries handle Kotlin data classes differently - please check commons/src/test/java/de/ey/commons/utils/TestJsonDecoding.kt for details. This results in a great deal of confusion among developers, unnecessary nullability and App crashes due to uncaught exceptions.

To address all those issues, new APIs have been added to PluginConfigManager. See below for details.

inline fun <reified T> getPluginConfigOrDefault(pluginId: String, default: T): T Returns T object if parsing was successful, or default if any exception was thrown. It's meant to be the primary way of working with plugin-configs

inline fun <reified T> getPluginConfigOrNull(pluginId: String): T? Returns T object if parsing was successful, null otherwise. It's meant to be used if failure of the parsing should be processed.

Migration guide

As an example, let's consider AokSelectionRepositoryImpl. Following code:

override fun getAokSelectionPluginConfig(): AokSelectionPluginConfig? {
val envConfig = Gson().fromJson(
pluginConfigManager.getPluginConfig(AokSelectionPlugin.getInstance().identifier),
AokSelectionPluginConfig::class.java,
)
return envConfig
}

should be simplified to:

override fun getAokSelectionPluginConfig(): AokSelectionPluginConfig {
return pluginConfigManager.getPluginConfigOrDefault(
PluginIdentifier.AokSelection.identifier, AokSelectionPluginConfig()
)
}

at the same time, data classes that represent the config should be made @Serializable:

@Serializable
data class AokSelectionPluginConfig(
@SerialName("aokId") val aokId: String = "",
....
)

Next

New APIs for parsing of JSON data other than plugin-config will be published soon.